from itertools import chain

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.generics import UpdateAPIView,RetrieveAPIView
from  rest_framework import serializers
from  api import models

from utils.auth import GeneralAuthentication,UserAuthentication

from  rest_framework import  status

from django.forms import model_to_dict

from django.db.models.fields import DateTimeField

import collections

class modifyPersonalModelSerialization(serializers.ModelSerializer):
    phone = serializers.CharField(source="telephone",read_only=True)
    token = serializers.CharField(read_only=True)
    submit_count = serializers.CharField(read_only=True)
    fans_count = serializers.CharField(read_only=True)
    class Meta:
        model = models.UserInfo
        exclude = ['id','telephone']



class modifyPersonalInformations(UpdateAPIView):
    serializer_class = modifyPersonalModelSerialization
    queryset = models.UserInfo.objects

    def get_object(self):
        query_set = self.get_queryset().filter(id = self.request.user.id).first()
        return query_set



# #########弃用的接口#############
# class modifyPersonalInformation(APIView):
#
#
#     def put(self,request,*args,**kwargs):
#         user_object = request.user
#         print(user_object)
#
#         print(request.data)
#         nickname = request.data.get('nickname')
#         avatar = request.data.get('avatar')
#         # models.UserInfo.objects.filter()
#         return Response()







class myFavorModelSerializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()
    create_date = serializers.DateTimeField(format="%Y-%m-%d")
    class Meta:
        model = models.News
        fields = "__all__"

    def get_user(self,obj):
        return model_to_dict(obj.user,fields=['nickname','avatar'])



class myFavor(APIView):
    authentication_classes = [UserAuthentication,]
    def get(self,request,*args,**kwargs):
        query_set = models.NewsFavorRecord.objects.filter(user=request.user).order_by('-id')
        news_list = [item.news for item in query_set]
        ser = myFavorModelSerializer(instance=news_list,many=True)
        return Response(ser.data,status=status.HTTP_200_OK)




#####################浏览用户主页#####################




##########默认的model_to_dict()方法是不能够返回时间字段的(如果你开了自动填充当前时间的代码)，我们需要重写model_to_dict()方法，实现时间字段的返回，注意是django.db.models.fields下的DateTimeField字段#######
##############如果开启了自动填充时间的代码，对应的时间字段里的属性,editable会被赋值为False,blank=True.就是因为这个原因导致时间字段被跳过了,重点是(editable会被赋值为False),具体看重写前的源代码.
##########重写model_to_dict()方法###############
def model_to_dict(instance, fields=None, exclude=None):
    """
    Return a dict containing the data in ``instance`` suitable for passing as
    a Form's ``initial`` keyword argument.

    ``fields`` is an optional list of field names. If provided, return only the
    named.

    ``exclude`` is an optional list of field names. If provided, exclude the
    named from the returned dict, even if they are listed in the ``fields``
    argument.
    """
    opts = instance._meta
    data = {}
    for f in chain(opts.concrete_fields, opts.private_fields, opts.many_to_many):
        if not getattr(f, "editable", False):
            if type(f) == DateTimeField:
                pass
            else:
                continue
        if fields is not None and f.name not in fields:
            continue
        if exclude and f.name in exclude:
            continue
            ##########源代码中是不能展开外键的，需要重写##########
        if f.name == "user":
            user_object = getattr(instance,f.name)
            data[f.name] = model_to_dict(user_object)
            continue
        data[f.name] = f.value_from_object(instance)
    return data








class pageViewModelSerializer(serializers.ModelSerializer):
    newsList = serializers.SerializerMethodField()
    is_follow = serializers.SerializerMethodField()
    class Meta:
        model = models.UserInfo
        exclude = ['telephone','token']

    def get_newsList(self,obj):
        news_list = models.News.objects.filter(user=obj)
        for item in news_list:
            item.create_date = item.create_date.strftime('%Y-%m-%d')
        return [model_to_dict(item) for item in news_list]

    def get_is_follow(self,obj):
        ###########在序列化类中获取路径上的参数pk##########
        pk = self.context['view'].kwargs.get('pk')

        exists = models.UserSubmit.objects.filter(user=self.context['request'].user,beuser_id=pk).exists()
        return exists



class pageView(RetrieveAPIView):
    queryset = models.UserInfo.objects

    serializer_class = pageViewModelSerializer







#############获取关注用户##############
class followUserModelSerializer(serializers.ModelSerializer):
    is_follow = serializers.SerializerMethodField()
    beuser = serializers.SerializerMethodField()
    class Meta:
        model = models.UserSubmit
        exclude = ['user']

    def get_is_follow(self,obj):
        return True

    def get_beuser(self,obj):
        user_object = models.UserInfo.objects.filter(id=obj.beuser.id).first()
        return model_to_dict(user_object)

class followUserView(APIView):
    authentication_classes = [UserAuthentication,]

    def get(self,request,*args,**kwargs):
        query_set = models.UserSubmit.objects.filter(user=request.user)
        ser = followUserModelSerializer(instance=query_set,many=True)
        return Response(ser.data)






################获取粉丝用户##################


class fansUserModelSerializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()
    is_follow = serializers.SerializerMethodField()
    class Meta:
        model = models.UserSubmit
        exclude = ['beuser']

    def get_user(self,obj):
        return model_to_dict(obj.user)

    def get_is_follow(self,obj):
        exists =  models.UserSubmit.objects.filter(user=obj.beuser,beuser=obj.user).exists()
        return exists


class fansUserView(APIView):
    authentication_classes = [UserAuthentication,]

    def get(self,request,*args,**kwargs):
        user_object = request.user
        query_set = models.UserSubmit.objects.filter(beuser=user_object)
        ser = fansUserModelSerializer(instance=query_set,many=True)
        return Response(ser.data)

